
var TypeTest = new YAHOO.tool.TestCase({

    name: "TypeTest",

    setUp: function () {},
    tearDown: function () {},

    /**
     * container.types.has()のテスト。
     */
    testHas: function () {
        var assert = YAHOO.util.Assert;
        var t = container.types;

        var TestObject = function(){}
        TestObject.prototype = {
            A: function(){},
            B: function(){},
            C: function(){},
            hoo:  function(){},
            X: "",
            Y: 1
        };
        var TestObject2 = function(){}
        TestObject2.prototype = {
            B: function(){},
            C: function(){},
            foo:  function(){},
            X: "",
            Y: 1
        };

        var obj  = new TestObject();
        var obj2 = new TestObject2();

        var type = t.has( "A" );
        assert.isTrue(  type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.has( "C" );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.has( "X" );
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.has( /A/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.has( /[a-zA-z]oo/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.has( /[a-zA-z]ooo/ );
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        assert.isTrue(  t.has( "A" ).equals(t.has( "A" )) );
        assert.isFalse( t.has( "A" ).equals(t.has( "B" )) );
        assert.isFalse( t.has( "A" ).equals(t.has( /A/ )) );

        assert.isTrue(  t.has( /A/ ).equals(t.has( /A/ )) );
        assert.isFalse( t.has( /A/ ).equals(t.has( /B/ )) );
        assert.isFalse( t.has( /A/ ).equals(t.has( "A" )) );


        type = t.has( "C", /B/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.has( /[a-zA-z]oo/, "A", "B" );
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        assert.isTrue(  type.equals(t.has( /[a-zA-z]oo/, "A", "B" )) );
        assert.isFalse( type.equals(t.has( /[a-zA-z]oo/, "X", "B" )) );
        assert.isFalse( type.equals(t.has( /[a-zA-z]oo/, "B" )) );
        assert.isFalse( type.equals(t.has( "B" )) );
        assert.isFalse( type.equals(t.has( /A/ )) );

        assert.isFalse(  type.equals(t.hasAny( /[a-zA-z]oo/, "A", "B" )) );


        assert.areEqual( type.toString(), t.has( /[a-zA-z]oo/, "A", "B" ).toString() );
        assert.areNotEqual( type.toString(), t.has( /[a-zA-z]oo/, "X", "B" ) );
        assert.areNotEqual( type.toString(), t.has( /[a-zA-z]oo/, "B" )) ;
        assert.areNotEqual( type.toString(), t.has( "B" )) ;
        assert.areNotEqual( type.toString(), t.has( /A/ )) ;

        assert.areNotEqual( type.toString(), t.hasAny( /[a-zA-z]oo/, "A", "B" ) );
    },

    /**
     * container.types.hasAny()のテスト。
     */
    testHasAny: function () {
        var assert = YAHOO.util.Assert;
        var t = container.types;

        var TestObject = function(){}
        TestObject.prototype = {
            A: function(){},
            B: function(){},
            C: function(){},
            hoo:  function(){},
            X: "",
            Y: 1
        };
        var TestObject2 = function(){}
        TestObject2.prototype = {
            B: function(){},
            C: function(){},
            foo:  function(){},
            X: "",
            Y: 1
        };

        var obj  = new TestObject();
        var obj2 = new TestObject2();

        var type = t.hasAny( "A" );
        assert.isTrue(  type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.hasAny( "C" );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.hasAny( "X" );
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.hasAny( /A/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.hasAny( /[a-zA-z]oo/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.hasAny( /[a-zA-z]ooo/ );
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        assert.isTrue(  t.hasAny( "A" ).equals(t.hasAny( "A" )) );
        assert.isFalse( t.hasAny( "A" ).equals(t.hasAny( "B" )) );
        assert.isFalse( t.hasAny( "A" ).equals(t.hasAny( /A/ )) );

        assert.isTrue(  t.hasAny( /A/ ).equals(t.hasAny( /A/ )) );
        assert.isFalse( t.hasAny( /A/ ).equals(t.hasAny( /B/ )) );
        assert.isFalse( t.hasAny( /A/ ).equals(t.hasAny( "A" )) );


        type = t.hasAny( "C", /B/ );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.hasAny( /X/, "A", "Y" );
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.hasAny( /[a-zA-z]oo/, "A", "B" );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        assert.isTrue(  type.equals(t.hasAny( /[a-zA-z]oo/, "A", "B" )) );
        assert.isFalse( type.equals(t.hasAny( /[a-zA-z]oo/, "X", "B" )) );
        assert.isFalse( type.equals(t.hasAny( /[a-zA-z]oo/, "B" )) );
        assert.isFalse( type.equals(t.hasAny( "B" )) );
        assert.isFalse( type.equals(t.hasAny( /A/ )) );

        assert.isFalse(  type.equals(t.has( /[a-zA-z]oo/, "A", "B" )) );


        assert.areEqual( type.toString(), t.hasAny( /[a-zA-z]oo/, "A", "B" ) );
        assert.areNotEqual( type.toString(), t.hasAny( /[a-zA-z]oo/, "X", "B" ) );
        assert.areNotEqual( type.toString(), t.hasAny( /[a-zA-z]oo/, "B" ) );
        assert.areNotEqual( type.toString(), t.hasAny( "B" ) );
        assert.areNotEqual( type.toString(), t.hasAny( /A/ ) );

        assert.areNotEqual( type.toString(), t.has( /[a-zA-z]oo/, "A", "B" ) );

    },


    /**
     * container.types.not()のテスト。
     */
    testNot: function () {
        var assert = YAHOO.util.Assert;
        var t = container.types;

        var TestObject = function(){}
        TestObject.prototype = {
            A: function(){},
            B: function(){},
            C: function(){},
            hoo:  function(){},
            X: "",
            Y: 1
        };
        var TestObject2 = function(){}
        TestObject2.prototype = {
            B: function(){},
            C: function(){},
            foo:  function(){},
            X: "",
            Y: 1
        };

        var obj  = new TestObject();
        var obj2 = new TestObject2();

        var type = t.not( t.hasAny( "A" ) );
        assert.isFalse(  type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.not(t.hasAny( "C" ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.not(t.hasAny( "X" ));
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.not(t.hasAny( /A/ ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.not(t.hasAny( /[a-zA-z]oo/ ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.not(t.hasAny( /[a-zA-z]ooo/ ));
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        assert.isTrue(  t.not(t.hasAny( "A" )).equals(t.not(t.hasAny( "A" ))) );
        assert.isFalse( t.not(t.hasAny( "A" )).equals(t.not(t.hasAny( "B" ))) );
        assert.isFalse( t.not(t.hasAny( "A" )).equals(t.not(t.hasAny( /A/ ))) );

        assert.isTrue(  t.not(t.hasAny( /A/ )).equals(t.not(t.hasAny( /A/ ))) );
        assert.isFalse( t.not(t.hasAny( /A/ )).equals(t.not(t.hasAny( /B/ ))) );
        assert.isFalse( t.not(t.hasAny( /A/ )).equals(t.not(t.hasAny( "A" ))) );


        type = t.not(t.hasAny( "C", /B/ ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.not(t.hasAny( /X/, "A", "Y" ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        type = t.not(t.hasAny( /[a-zA-z]oo/, "A", "B" ));
        assert.isFalse( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        assert.isTrue(  type.equals(t.not(t.hasAny( /[a-zA-z]oo/, "A", "B" ))) );
        assert.isFalse( type.equals(t.not(t.hasAny( /[a-zA-z]oo/, "X", "B" ))) );
        assert.isFalse( type.equals(t.not(t.hasAny( /[a-zA-z]oo/, "B" ))) );
        assert.isFalse( type.equals(t.not(t.hasAny( "B" ))) );
        assert.isFalse( type.equals(t.not(t.hasAny( /A/ ))) );

        assert.isFalse(  type.equals(t.not(t.has( /[a-zA-z]oo/, "A", "B" ))) );


        assert.areEqual( type.toString(), t.not(t.hasAny( /[a-zA-z]oo/, "A", "B" )) );
        assert.areNotEqual( type.toString(), t.not(t.hasAny( /[a-zA-z]oo/, "X", "B" )) );
        assert.areNotEqual( type.toString(), t.not(t.hasAny( /[a-zA-z]oo/, "B" )) );
        assert.areNotEqual( type.toString(), t.not(t.hasAny( "B" )) );
        assert.areNotEqual( type.toString(), t.not(t.hasAny( /A/ )) );

        assert.areNotEqual( type.toString(), t.not(t.has( /[a-zA-z]oo/, "A", "B" )) );

    },

    testBasic : function() {
        var TestObject = function(){}
        TestObject.prototype = {
            A: function(){},
            B: function(){},
            C: function(){}
        };
        var TestObject2 = function(){}
        TestObject2.prototype = {
            B: function(){},
            C: function(){}
        };
        var obj  = new TestObject();
        var obj2 = new TestObject2();

        var assert = YAHOO.util.Assert;

        // ユーテイリティへの参照
        var t = container.types;

        // メソッドA,Bを持つType
        var type = t.has( "C", "A" );

        // isImplementor() でオブジェクトが指定されたメソッドを持つか評価する。
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        // メソッドA,またはCを持つType
        type = t.hasAny( "C", /A/ ); // 正規表現も指定できる。また、引数の数に制限はない。

        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

        // Typeのネストも可能
        type = t.has(
            "C",
            t.hasAny( "A", /X/)
        );
        assert.isTrue( type.isImplementor(obj) );
        assert.isFalse( type.isImplementor(obj2) );

        type = t.hasAny(
            "C",
            t.has( "A", /X/)
        );
        assert.isTrue( type.isImplementor(obj) );
        assert.isTrue( type.isImplementor(obj2) );

    }
});
